/*     */ package de.tum.in.eist.im.server;
/*     */ 
/*     */ import com.google.gwt.user.server.rpc.RemoteServiceServlet;
/*     */ import de.tum.in.eist.im.client.ChatService;
/*     */ import de.tum.in.eist.im.client.domain.AbstractEvent;
/*     */ import de.tum.in.eist.im.client.domain.HeartbeatEvent;
/*     */ import de.tum.in.eist.im.client.domain.Message;
/*     */ import de.tum.in.eist.im.client.domain.MessageEvent;
/*     */ import de.tum.in.eist.im.client.domain.NewMessagesChunk;
/*     */ import de.tum.in.eist.im.client.domain.User;
/*     */ import de.tum.in.eist.im.client.domain.UserEvent;
/*     */ import java.util.ArrayList;
/*     */ import java.util.Calendar;
/*     */ import java.util.Date;
/*     */ import java.util.HashMap;
/*     */ import java.util.Iterator;
/*     */ import java.util.LinkedList;
/*     */ import java.util.List;
/*     */ import java.util.Map;
/*     */ import java.util.Set;
/*     */ import java.util.concurrent.BlockingDeque;
/*     */ import java.util.concurrent.LinkedBlockingDeque;
/*     */ 
/*     */ public class ChatServiceImpl extends RemoteServiceServlet
/*     */   implements ChatService
/*     */ {
/*     */   
/*     */   private static final int USER_EVENT_QUEUE_SIZE = 1000;
/*     */   private static final long serialVersionUID = 1L;
/*  35 */   private Map<User, BlockingDeque<AbstractEvent>> userEvents = new HashMap();
/*     */   private Calendar calendar;
/*     */   
/*     */   private List<User> loggedInUsers;
/*     */   private List<User> registeredUsers;
/*     */   private List<Message> allMessages;
/*     */ 
/*     */   public ChatServiceImpl()
/*     */   {
/*  46 */     this.loggedInUsers = new ArrayList();
/*  47 */     initRegisteredUsers();
/*  48 */     this.allMessages = new ArrayList();
/*  49 */     this.calendar = Calendar.getInstance();
/*  50 */     
/*     */   }
/*     */ 
/*     */   private void initRegisteredUsers()
/*     */   {
/*  55 */     this.registeredUsers = new ArrayList();
/*     */   }
/*     */ 
/*     */   
/*  59 */     
/*  60 */   
/*  61 */   
/*  62 */   
/*  63 */   
/*     */   
/*     */ 
/*     */   private void addEvent(User loggedInUser, AbstractEvent event)
/*     */   {
/*  70 */     BlockingDeque userEventQueue = (BlockingDeque)this.userEvents.get(loggedInUser);
/*  71 */     if (userEventQueue.size() < 900)
/*  72 */       userEventQueue.add(event);
/*     */   }
/*     */ 
/*     */   public void sendMessage(Message message)
/*     */   {
/*  79 */     this.allMessages.add(message);
/*     */ 
/*  81 */     MessageEvent messageEvent = new MessageEvent();
/*  82 */     messageEvent.setTimestamp(this.calendar.getTimeInMillis());
/*  83 */     messageEvent.setMessage(message);
/*  84 */     for (User user : this.userEvents.keySet())
/*  85 */       addEvent(user, messageEvent);
/*     */   }
/*     */ 
/*     */   public boolean login(User user)
/*     */   {
/*  93 */     if ((isRegistered(user)) && (authenticate(user))) {
/*  94 */       if (this.userEvents.get(user) == null) {
/*  95 */         this.userEvents.put(user, 
/*  96 */           new LinkedBlockingDeque(1000));
/*     */       }
/*     */ 
/*  99 */       this.loggedInUsers.add(user);
/*     */ 
/* 101 */       UserEvent userEvent = new UserEvent();
/* 102 */       userEvent.setTimestamp(this.calendar.getTimeInMillis());
/* 103 */       userEvent.setLogin(true);
/* 104 */       userEvent.setUser(user);
/* 105 */       Iterator localIterator = this.userEvents.keySet().iterator();
/*     */       while (true) { User loggedInUser = (User)localIterator.next();
/* 106 */         addEvent(loggedInUser, userEvent);
/*     */ 
/* 105 */         if (!(localIterator.hasNext()))
/*     */         {
/* 108 */           label126: return true; } }
/*     */     }
/* 110 */     return false;
/*     */   }
/*     */ 
/*     */   private synchronized boolean isRegistered(User user) {
/* 114 */     return true;
/*     */   }
/*     */ 
/*     */   private boolean authenticate(User userToAuthenticate)
/*     */   {
/* 129 */     return true;
/*     */   }
/*     */ 
/*     */   public boolean logout(User user)
/*     */   {
/* 134 */     if (this.userEvents.get(user) != null) {
/* 135 */       this.userEvents.put(user, null);
/* 136 */       this.userEvents.remove(user);
/*     */     }
/*     */ 
/* 139 */     this.loggedInUsers.remove(user);
/*     */ 
/* 141 */     UserEvent userEvent = new UserEvent();
/* 142 */     userEvent.setTimestamp(this.calendar.getTimeInMillis());
/* 143 */     userEvent.setLogin(false);
/* 144 */     userEvent.setUser(user);
/* 145 */     for (User loggedInUser : this.userEvents.keySet()) {
/* 146 */       addEvent(loggedInUser, userEvent);
/*     */     }
/* 148 */     return true;
/*     */   }
/*     */ 
/*     */   public List<AbstractEvent> getEventsBlocking(User user)
/*     */   {
/* 155 */     
/* 156 */     BlockingDeque eventsForUser = (BlockingDeque)this.userEvents.get(user);
/* 157 */     LinkedList result = new LinkedList();
/*     */     do
/*     */       try {
/* 160 */         eventsForUser = (BlockingDeque)this.userEvents.get(user);
/* 161 */         result.add((AbstractEvent)eventsForUser.takeFirst());
/*     */       } catch (InterruptedException e) {
/* 163 */         e.printStackTrace();
/*     */       }
/* 158 */     while (!(
/* 165 */       eventsForUser.isEmpty()));
/* 166 */     return result;
/*     */   }
/*     */ 
/*     */   
/*     */   
/* 171 */   
/* 172 */   
/* 173 */   
/*     */   
/*     */ 
/*     */   public List<User> getLoggedInUsers()
/*     */   {
/* 180 */     return this.loggedInUsers;
/*     */   }
/*     */ 
/*     */   public void registerNewUser(User newUser)
/*     */   {
/* 186 */     this.registeredUsers.add(newUser);
/*     */   }
/*     */ 
/*     */   public NewMessagesChunk getNewMessages(long clientLastTimestamp)
/*     */   {
/* 191 */     List<Message> newMessages = new ArrayList<Message>();
/* 192 */     for (int i = this.allMessages.size() - 1; i >= 0; --i) {
/* 193 */       Message message = (Message)this.allMessages.get(i);
/* 194 */       if (message.getTimestamp() > clientLastTimestamp) {
/* 195 */         newMessages.add(0, message);
/*     */       }
/*     */     }
/* 198 */     long newClientTimestamp = new Date().getTime();
/* 199 */     NewMessagesChunk result = new NewMessagesChunk();
/* 200 */     result.setMessages(newMessages);
/* 201 */     result.setTimestamp(newClientTimestamp);
/* 202 */     return result;
/*     */   }
/*     */ 
/*     */ 
/*     */  
/* 209 */ 
/*     */  
/*     */ }